# This code is part of cqlib.
#
# Copyright (C) 2024 China Telecom Quantum Group, QuantumCTek Co., Ltd.,
# Center for Excellence in Quantum Information and Quantum Physics.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

""" Commutation relations for common gates """

gates_commutations = {
    "X": {
        "X": True,
        "CX": {
            (0,): False,
            (1,): True,
        },
        "CNOT": {
            (0,): False,
            (1,): True,
        },
        "CCX": {
            (0,): False,
            (1,): False,
            (2,): True,
        },
        "CCNOT": {
            (0,): False,
            (1,): False,
            (2,): True,
        },
        "CZ": False,
        "SD": False,
        "SWAP": False,
        "TD": False,
        "Y": False,
        "Z": False,
    },
    "CX": {
        "CX": {
            (0, 1): True,
            (0, None): True,
            (1, 0): False,
            (1, None): False,
            (None, 0): False,
            (None, 1): True,
        },
        "CNOT": {
            (0, 1): True,
            (0, None): True,
            (1, 0): False,
            (1, None): False,
            (None, 0): False,
            (None, 1): True,
        },
        "CCX": {
            (0, 1): False,
            (0, 2): True,
            (0, None): True,
            (1, 0): False,
            (1, 2): True,
            (1, None): True,
            (2, 0): False,
            (2, 1): False,
            (2, None): False,
            (None, 0): False,
            (None, 1): False,
            (None, 2): True,
        },
        "CCNOT": {
            (0, 1): False,
            (0, 2): True,
            (0, None): True,
            (1, 0): False,
            (1, 2): True,
            (1, None): True,
            (2, 0): False,
            (2, 1): False,
            (2, None): False,
            (None, 0): False,
            (None, 1): False,
            (None, 2): True,
        },
        "CZ": {
            (0, 1): False,
            (0, None): True,
            (1, 0): False,
            (1, None): True,
            (None, 0): False,
            (None, 1): False,
        },
        "SWAP": False,
    },

    "CCX": {
        "CCX": {
            (0, 1, 2): True,
            (0, 1, None): True,
            (0, 2, 1): False,
            (0, 2, None): False,
            (0, None, 1): False,
            (0, None, 2): True,
            (0, None, None): True,
            (1, 0, 2): True,
            (1, 0, None): True,
            (1, 2, 0): False,
            (1, 2, None): False,
            (1, None, 0): False,
            (1, None, 2): True,
            (1, None, None): True,
            (2, 0, 1): False,
            (2, 0, None): False,
            (2, 1, 0): False,
            (2, 1, None): False,
            (2, None, 0): False,
            (2, None, 1): False,
            (2, None, None): False,
            (None, 0, 1): False,
            (None, 0, 2): True,
            (None, 0, None): True,
            (None, 1, 0): False,
            (None, 1, 2): True,
            (None, 1, None): True,
            (None, 2, 0): False,
            (None, 2, 1): False,
            (None, 2, None): False,
            (None, None, 0): False,
            (None, None, 1): False,
            (None, None, 2): True,
        },
    },

    "CZ": {
        "CCX": {
            (0, 1): True,
            (0, 2): False,
            (0, None): True,
            (1, 0): True,
            (1, 2): False,
            (1, None): True,
            (2, 0): False,
            (2, 1): False,
            (2, None): False,
            (None, 0): True,
            (None, 1): True,
            (None, 2): False,
        },
        "CZ": True,
        "SWAP": {
            (0, 1): True,
            (0, None): False,
            (1, 0): True,
            (1, None): False,
            (None, 0): False,
            (None, 1): False,
        },
    },
    "H": {
        "X": False,
        "CX": False,
        "CZ": False,
        "H": True,
        "S": False,
        "SD": False,
        "SWAP": False,
        "T": False,
        "TD": False,
        "Y": False,
        "Z": False,
    },

    "S": {
        "X": False,
        "CX": {
            (0,): True,
            (1,): False,
        },
        "CCX": {
            (0,): True,
            (1,): True,
            (2,): False,
        },
        "CZ": True,
        "S": True,
        "SD": True,
        "SWAP": False,
        "T": True,
        "TD": True,
        "Y": False,
        "Z": True,
    },
    "SD": {
        "CX": {
            (0,): True,
            (1,): False,
        },
        "CCX": {
            (0,): True,
            (1,): True,
            (2,): False,
        },

        "CZ": True,
        "SWAP": False,
        "TD": True,
    },
    "SWAP": {
        "CCX": {
            (0, 1): True,
            (0, 2): False,
            (0, None): False,
            (1, 0): True,
            (1, 2): False,
            (1, None): False,
            (2, 0): False,
            (2, 1): False,
            (2, None): False,
            (None, 0): False,
            (None, 1): False,
            (None, 2): False,
        },
        "SWAP": {
            (0, 1): True,
            (0, None): False,
            (1, 0): True,
            (1, None): False,
            (None, 0): False,
            (None, 1): False,
        },
    },
    "T": {
        "X": False,
        "CX": {
            (0,): True,
            (1,): False,
        },
        "CCX": {
            (0,): True,
            (1,): True,
            (2,): False,
        },
        "CZ": True,
        "SWAP": False,
        "T": True,
        "TD": True,
        "Y": False,
        "Z": True,
    },
    "TD": {
        "CX": {
            (0,): True,
            (1,): False,
        },
        "CCX": {
            (0,): True,
            (1,): True,
            (2,): False,
        },
        "CZ": True,
        "SWAP": False,
        "TD": True,
    },
    "Y": {
        "CX": False,
        "CCX": False,
        "CZ": False,
        "SD": False,
        "SWAP": False,
        "TD": False,
        "Y": True,
        "Z": False,
    },
    "Z": {
        "CX": {
            (0,): True,
            (1,): False,
        },
        "CCX": {
            (0,): True,
            (1,): True,
            (2,): False,
        },
        "CZ": True,
        "SD": True,
        "SWAP": False,
        "TD": True,
        "Z": True,
    }
}
